#include "stdafx.h"

namespace classifier_test
{

ensemble_classifier::ensemble_classifier()
{

}

ensemble_classifier::ensemble_classifier(const ensemble_classifier& Val)
	: classifier(Val)
{
	Classifiers = Val.Classifiers;
	Weights = Val.Weights;
}

smart_ptr<classifier> ensemble_classifier::clone() const
{
	return make_smart_ptr(new ensemble_classifier(*this));
}

void ensemble_classifier::serialize(serializer& Serializer)
{
	throw runtime_error("ensemble_classifier is nonserializable");
}

void ensemble_classifier::add(classifier* Classifier, double Weight)
{
	Classifiers.push_back(Classifier);
	Weights.push_back(Weight);
}

void ensemble_classifier::train(subarray<const record* const> Data)
{
	for (int I = 0; I < (int)Classifiers.size(); I++)
		Classifiers[I]->train(Data);
}

classifier_test::discr_value ensemble_classifier::classify(const record& Record) const
{
	array<double> P;
	estimate(Record, P);
	return max_element(P.begin(), P.end()) - P.begin();
}

void ensemble_classifier::estimate(const record& Record, array<double>& Probs) const
{
	Probs.assign(ClassCount, 0);
	array<double> P;
	for (int I = 0; I < (int)Classifiers.size(); I++)
	{
		Classifiers[I]->estimate(Record, P);
		for (int J = 0; J < P.size(); J++) Probs[J] += P[J] * Weights[I];
	}
	normalize_probabilities(Probs);
}

}
